use crate::gen_title;

pub fn ch2_7_1() {
    gen_title("ch2_7_1", 18);

    let x = 5;
    let y = &x;

    assert_eq!(5, x);
    assert_eq!(5, *y);
    println!("{}", y);
}

pub fn ch2_7_2() {
    gen_title("ch2_7_2", 18);

    let s1 = String::from("hello");
    let len = calculate_length(&s1);
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

pub fn ch2_7_3() {
    gen_title("ch2_7_3", 18);

    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

pub fn ch2_7_4() {
    gen_title("ch2_7_4", 18);

    let mut s = String::from("hello");

    {
        let r1 = &mut s;
        println!("{}", r1);
    }

    let r2 = &mut s;
    println!("{}", r2);
}

pub fn ch2_7_5() {
    gen_title("ch2_7_5", 18);

    let mut s = String::from("hello");

    {
        let r3 = &mut s;
        println!("{}", r3);
    }

    let r1 = &s;
    let r2 = &s;

    println!("{}, {}", r1, r2);
}

pub fn ch2_7_6() {
    gen_title("ch2_7_6", 18);

    let mut s = String::from("hello");

    let r1 = &s;
    let r2 = &s;
    println!("{}, {}", r1, r2);

    let r3 = &mut s;
    println!("{}", r3);
}

pub fn ch2_7_pra_1() {
    gen_title("ch2_7_pra_1", 18);

    let x = 5;
    let p = &x;
    println!("x 的内存地址是: {:p}", p);
}

pub fn ch2_7_pra_2() {
    gen_title("ch2_7_pra_2", 18);

    let x = 5;
    let y = &x;

    assert_eq!(5, *y);

    println!("{}, {}", x, *y);
}

pub fn ch2_7_pra_3() {
    gen_title("ch2_7_pra_3", 18);

    let mut s = String::from("hello, ");

    borrow_object(&s);
    println!("{}", s);
}

fn borrow_object(s: &String) {
    println!("{}", s);
}

pub fn ch2_7_pra_4() {
    gen_title("ch2_7_pra_4", 18);

    let mut s = String::from("hello, ");

    push_str(&mut s);
    println!("{}", s);
}

fn push_str(s: &mut String) {
    s.push_str("world");
}

pub fn ch2_7_pra_5() {
    gen_title("ch2_7_pra_5", 18);

    let mut s = String::from("hello, ");

    let p = &mut s;

    p.push_str("world");

    println!("{}", p);
    println!("{}", s);
}

pub fn ch2_7_pra_6() {
    gen_title("ch2_7_pra_5", 18);

    let c = '中';

    let r1 = &c;

    let ref r2 = c;

    assert_eq!(*r1, *r2);
    println!("{}, {}", r1, r2);

    assert_eq!(get_addr(r1), get_addr(r2));
    println!("{}, {}", get_addr(r1), get_addr(r2));
}

fn get_addr(r: &char) -> String {
    format!("{:p}", r)
}

pub fn ch2_7_pra_7() {
    gen_title("ch2_7_pra_7", 18);

    let mut s = String::from("hello");

    let r1 = &s;
    let r2 = &s;

    println!("{}, {}", r1, r2)
}

pub fn ch2_7_pra_8() {
    gen_title("ch2_7_pra_8", 18);

    let mut s = String::from("hello, ");
    borrow_object(&s);

    s.push_str("world");

    println!("{}", s);
}

pub fn ch2_7_pra_9() {
    gen_title("ch2_7_pra_9", 18);

    let mut s = String::from("hello, ");

    let r1 = &mut s;
    r1.push_str("world");

    let r2 = &mut s;
    r2.push_str("!");

    println!("{}", r2);
}

pub fn ch2_7_pra_10() {
    gen_title("ch2_7_pra_10", 18);

    let mut s = String::from("hello, ");

    let r1 = &mut s;
    println!("{}", r1);

    let r2 = &mut s;
    println!("{}", r2);
}
